home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Game-Power
/
Amiga Game-Power.iso
/
pd mix ii
/
access
/
backup
/
backup.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-05-20
|
8KB
|
397 lines
#include "dir.h"
#include "backup.h"
extern char *strsave ();
extern char *pop ();
extern int push ();
extern char *build_name ();
extern int in_dir ();
extern int out_of_date ();
extern struct FileLock *CreateDir ();
void *stack = NULL;
char sprbuf[ 1024 ];
struct DateStamp bdate;
int first_time;
main ( argc , argv )
int argc;
char **argv;
{
FILE *fp;
#define LINE_SIZE 100
char linebuf[ LINE_SIZE ];
char *p , *parm1 , *parm2;
first_time = FALSE;
argc--;
argv++;
while ( argc > 0 && argv[0][0] == '-' ) {
switch ( argv[0][1] ) {
case 'f' :
first_time = TRUE;
break;
default :
puts ( "Unknown option %s\n" , argv[0] );
exit ( 1 );
}
argc--;
argv++;
}
if ( argc == 2 ) {
backup ( argv[0] , argv[1] );
}
else if ( argc == 1 ) {
/* read from DO_BACKUP file on destination drive. */
/* it should contain lines containing two parameters for the */
/* backup command (eg: h2:thai thai-backup:) */
fp = fopen ( build_name ( argv[0] , DO_BACKUP ) , "r" );
if ( fp == NULL ) {
printf ( "usage: unable to find %s file on destination disk\n" ,
DO_BACKUP );
}
else {
while ( fgets ( linebuf , LINE_SIZE , fp ) != NULL ) {
p = linebuf;
while ( isspace ( *p ) )
p++;
if ( *p == '\0' )
continue;
parm1 = p;
while ( !isspace ( *p ) )
p++;
*p++ = '\0';
while ( isspace ( *p ) )
p++;
if ( *p == '\0' )
continue;
parm2 = p;
while ( !isspace ( *p ) )
p++;
*p++ = '\0';
while ( isspace ( *p ) )
p++;
if ( *p != '\0' ) {
printf ( "illegal syntax in %s file\n" , DO_BACKUP );
break;
}
printf ( "\nbackup %s %s\n\n" , parm1 , parm2 );
backup ( parm1 , parm2 );
}
fclose ( fp );
}
}
else {
printf ( "usage: backup from to\n" );
printf ( "or backup todisk\n" );
}
}
backup ( from , to )
char *from , *to;
{
struct dir_st *dir , *todir;
char *path;
struct dir_st *p;
int isdir;
struct DPTR *dptr;
struct FileLock *lock;
FILE *fp;
struct FileInfoBlock *fib;
int checkdir;
lock = Lock ( build_name ( to , BACKUP_FILE_NAME ) , (LONG)ACCESS_READ );
if ( lock == NULL ) {
if ( ! first_time ) {
puts ( ".backup not found: use -f for first time backup" );
exit ( 1 );
}
bdate.ds_Days = 0;
bdate.ds_Minute = 0;
bdate.ds_Tick = 0;
}
else {
fib = (struct FileInfoBlock *)
AllocMem ( (LONG) sizeof ( struct FileInfoBlock ) ,
(LONG) MEMF_PUBLIC );
if ( fib != NULL && Examine ( lock , fib ) )
bdate = fib->fib_Date;
else {
bdate.ds_Days = 0;
bdate.ds_Minute = 0;
bdate.ds_Tick = 0;
}
if ( fib != NULL )
FreeMem ( fib , (LONG) sizeof ( struct FileInfoBlock ) );
UnLock ( lock );
}
fp = fopen ( build_name ( to , BACKUP_FILE_NAME ) , "w" );
if ( fp == NULL ) {
puts ( "Failed to create .backup file for time stamp" );
return ( 0 );
}
fclose ( fp );
if ( ! push ( &stack , "" ) ) {
puts ( "Aborting" );
return ( 0 );
}
while ( path = pop ( &stack ) ) {
printf ( "Searching %s\n" , build_name ( from , path ) );
dir = getdir ( build_name ( from , path ) );
if ( dir == NULL ) {
puts ( "Aborting" );
return ( 0 );
}
/* if original directory changed since last backup, a file */
/* may have been deleted. If this is so, must do dir on dest too */
checkdir = FALSE;
dptr = dopen ( build_name ( from , path ) , &isdir );
if ( dptr == NULL || ! isdir ) {
puts ( "Internal error!!!" );
freedir ( dir );
return ( 0 );
}
if ( out_of_date ( &dptr->fib->fib_Date ) )
checkdir = TRUE;
dclose ( dptr );
/* ok, must also check destination disk in case files there */
/* have been added */
dptr = dopen ( build_name ( to , path ) , &isdir );
if ( dptr == NULL || ! isdir ) {
if ( dptr != NULL && ! isdir ) {
/* Found a file where we want a directory */
rm_file ( to , "" , path , isdir );
}
printf ( "Creating %s\n" ,
build_name ( to , path ) );
lock = CreateDir ( build_name ( to , path ) );
if ( lock == NULL ) {
printf ( "Failed to create %s\n" ,
build_name ( to , path ) );
freedir ( dir );
dclose ( dptr );
return ( 0 );
}
UnLock ( lock );
}
else {
/* now, check date on destination directory. if changed, then */
/* files may have been created (which will have to be deleted) */
if ( out_of_date ( &dptr->fib->fib_Date ) )
checkdir = TRUE;
}
dclose ( dptr );
if ( checkdir ) {
/* Have to check if files have been deleted. */
/* To do this, must do a dir on destination drive. */
printf ( "Searching %s\n" , build_name ( to , path ) );
todir = getdir ( build_name ( to , path ) );
if ( todir == NULL ) {
puts ( "Aborting" );
freedir ( dir );
return ( 0 );
}
for ( p = todir->next; p != NULL; p = p->next ) {
if ( ! in_dir ( p->filename , dir ) )
rm_file ( to , path , p->filename , p->dir );
}
freedir ( todir );
}
for ( p = dir->next; p != NULL; p = p->next ) {
if ( p->dir ) {
if ( ! push ( &stack , build_name ( path , p->filename ) ) ) {
freedir ( dir );
puts ( "Aborting" );
return ( 0 );
}
}
else {
if ( out_of_date ( &p->date ) )
copy_file ( from , to , path , p->filename );
}
}
}
return ( 1 );
}
#define BSIZE 10000
copy_file ( from , to , path , filename )
char *from , *to , *path , *filename;
{
FILE *fromfp , *tofp;
static char buf[ BSIZE ];
int bytes;
if ( path == NULL || path[0] == '\0' )
strcpy ( sprbuf , filename );
else
sprintf ( sprbuf , "%s/%s" , path , filename );
fromfp = fopen ( build_name ( from , sprbuf ) , "r" );
if ( fromfp == NULL ) {
printf ( "Failed to open '%s' for copying\n" ,
build_name ( from , sprbuf ) );
return;
}
tofp = fopen ( build_name ( to , sprbuf ) , "w" );
if ( tofp == NULL ) {
fclose ( fromfp );
printf ( "Failed to create '%s' to copy to\n" ,
build_name ( to , sprbuf ) );
return;
}
printf ( "Copying %s ... " , sprbuf );
fflush ( stdout );
while ( ( bytes = fread ( buf , 1 , BSIZE , fromfp ) ) > 0 ) {
if ( fwrite ( buf , 1 , bytes , tofp ) != bytes ) {
printf ( "write error, " );
break;
}
}
fclose ( tofp );
fclose ( fromfp );
puts ( "done" );
}
rm_file ( root , path , filename , isdir )
char *root;
char *path;
char *filename;
int isdir;
{
struct dir_st *p , *dir;
char *buf;
if ( path == NULL || path[0] == '\0' ) {
strcpy ( sprbuf , filename );
buf = strsave ( sprbuf );
}
else {
sprintf ( sprbuf , "%s/%s" , path , filename );
buf = strsave ( sprbuf );
}
if ( strcmp ( buf , BACKUP_FILE_NAME ) == 0 )
return;
if ( buf == NULL ) {
puts ( "Out of memory!\n" );
return;
}
printf ( "Deleting %s %s\n" ,
isdir ? "directory" : "file" ,
build_name ( root , buf ) );
if ( isdir ) {
printf ( "Searching %s\n" , build_name ( root , buf ) );
dir = getdir ( build_name ( root , buf ) );
if ( dir == NULL ) {
printf ( "Failed to open directory %s\n" ,
build_name ( root , buf ) );
}
else {
for ( p = dir->next; p != NULL; p = p->next )
rm_file ( root , build_name ( path , filename ) ,
p->filename , p->dir );
freedir ( dir );
/* Delete the directory */
DeleteFile ( build_name ( root , buf ) );
}
}
else
DeleteFile ( build_name ( root , buf ) );
free ( buf );
}
int
in_dir ( filename , dir )
char *filename;
struct dir_st *dir;
{
struct dir_st *p;
for ( p = dir->next; p != NULL; p = p->next )
if ( strcmp ( p->filename , filename ) == 0 )
return ( 1 );
return ( 0 );
}
char *
build_name ( root , filename )
char *root , *filename;
{
static char buf[ 512 ];
strcpy ( buf , root );
if ( buf[0] != '\0' && buf[ strlen ( buf ) - 1 ] != ':' )
strcat ( buf , "/" );
strcat ( buf , filename );
return ( buf );
}
char *
strsave ( s )
char *s;
{
char *p;
p = malloc ( strlen ( s ) + 1 );
if ( p != NULL )
strcpy ( p , s );
return ( p );
}
int
out_of_date ( date )
struct DateStamp *date;
{
if ( date->ds_Days < bdate.ds_Days )
return ( 0 );
if ( date->ds_Days > bdate.ds_Days )
return ( 1 );
if ( date->ds_Minute < bdate.ds_Minute )
return ( 0 );
if ( date->ds_Minute > bdate.ds_Minute )
return ( 1 );
if ( date->ds_Tick < bdate.ds_Tick )
return ( 0 );
if ( date->ds_Tick > bdate.ds_Tick )
return ( 1 );
return ( 1 );
}
/* Aztec C playing up! Used by perror() */
int sys_nerr = -1;
char *sys_errlist[1];